package middleware

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"order-srv/internal/biz/common"
	"order-srv/internal/biz/vo"
	"strings"
)

type SkipAuth struct {
	FullPath string
	Method   string
}

func Auth(skipAuthList []SkipAuth) gin.HandlerFunc {
	return func(c *gin.Context) {

		// 获取请求的原始路由信息
		//originalRoute := c.FullPath()
		//originalMethod := c.Request.Method
		//
		//fmt.Printf("Original Route: %s\n", originalRoute)
		//fmt.Printf("Original Method: %s\n", originalMethod)

		// 跳过验证
		for _, v := range skipAuthList {
			if v.FullPath == c.FullPath() && v.Method == c.Request.Method {
				c.Next()
				return
			}
		}

		var authorization = c.Request.Header.Get("authorization")
		// 没有 token 或者 token 里不包含 Bearer 关键字，都是无效 token
		if authorization == "" || !strings.Contains(authorization, "Bearer ") {
			apiRes := vo.NewTokenInvalid()
			c.JSON(http.StatusOK, apiRes)
			c.Abort()
			return
		}

		var authorizationArr = strings.Split(authorization, "Bearer")
		if len(authorizationArr) != 2 {
			apiRes := vo.NewTokenInvalid()
			c.JSON(http.StatusOK, apiRes)
			c.Abort()
			return
		}
		var token = strings.TrimSpace(authorizationArr[1])
		if token == "" {
			apiRes := vo.NewTokenInvalid()
			c.JSON(http.StatusOK, apiRes)
			c.Abort()
			return
		}
		fmt.Println(token)

		// token 校验
		claim, err := common.ParseToken(token)
		if claim == nil || err != nil {
			apiRes := vo.NewTokenInvalid()
			c.JSON(http.StatusOK, apiRes)
			c.Abort()
			return
		}

		// Id 是用户登录时写入的，没有数据有异常
		if claim.Id == "" {
			apiRes := vo.NewTokenInvalid()
			c.JSON(http.StatusOK, apiRes)
			c.Abort()
			return
		}

		// 到此，才算校验真正通过，其实网关能校验通过就行，在没有网关的情况下，需要业务应用自己校验

		// 在 token 快要过期的时候，换取新的 token，使前端登录一次能一直用
		//if claim.ExpiresAt-time.Now().Unix() < 60 { // 说明快过期了，换取新 token,60秒 = 1分钟
		//	newToken := util.JwtEncryption(claim)
		//	c.Header("new-token", newToken) // 前端在响应头里拿到 New-Token ，重新写入缓冲，达到刷新Token
		//}

		//fmt.Println(claim.Id) // 可以在业务里使用
		//c.Set("claim", claim)
		c.Next()
	}
}
